package com.net.client.netty;

import java.net.InetSocketAddress;
import java.util.concurrent.Executors;

import org.jboss.netty.bootstrap.ClientBootstrap;
import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.buffer.ChannelBuffers;
import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelFuture;
import org.jboss.netty.channel.ChannelPipeline;
import org.jboss.netty.channel.ChannelPipelineFactory;
import org.jboss.netty.channel.DefaultChannelPipeline;
import org.jboss.netty.channel.socket.nio.NioClientSocketChannelFactory;
import org.jboss.netty.handler.codec.frame.LengthFieldBasedFrameDecoder;
import org.jboss.netty.handler.codec.frame.LengthFieldPrepender;

import com.net.client.NetClient;
import com.net.utils.PrintUtil;
import com.utils.UTF8;

/**
 * @author yangqifan
 * 
 *  客户端 ,不分mina和netty通用,这里使用netty客户端<br>
 * 
 *  后面会用于机器人,注意设计<br>
 */
public class NettyClient implements NetClient {
	private Channel channel = null;
	
	private ClientBootstrap bootstrap = null;

	public NettyClient() {}

	@Override
	public void connect(String serverIp, int port) {

		// Configure the client.
		bootstrap = new ClientBootstrap(new NioClientSocketChannelFactory(Executors.newCachedThreadPool(), Executors.newCachedThreadPool()));

		bootstrap.setOption("child.tcpNoDelay", true);
		bootstrap.setOption("child.keepAlive", true);
		bootstrap.setOption("child.sendBufferSize", 8192 * 4);
		bootstrap.setOption("child.receiveBufferSize", 8192 * 2);
		// Set up the pipeline factory.
		bootstrap.setPipelineFactory(new ChannelPipelineFactory() {
			public ChannelPipeline getPipeline() throws Exception {
				DefaultChannelPipeline result = new DefaultChannelPipeline();

				result.addLast("frameDecoder", new LengthFieldBasedFrameDecoder(Integer.MAX_VALUE, 0, 4, 0, 4));// 按长度读取出来

				result.addLast("frameEncoder", new LengthFieldPrepender(4));

				result.addLast("handler", new NettyHandler());

				return result;
			}
		});

		// Start the connection attempt.
		ChannelFuture future = bootstrap.connect(new InetSocketAddress(serverIp, port));

		channel = future.awaitUninterruptibly().getChannel();
		PrintUtil.info("连接服务器成功");
	}

	@Override
	public void sendMsg(Object msg) {
		if(msg instanceof String){
			try {
				// lock.lock();//单线程的executor不用枷锁
				ChannelBuffer channelBuffer = ChannelBuffers.wrappedBuffer(((String) msg).getBytes(UTF8.get()));
				System.out.println(new String(channelBuffer.array(), UTF8.get()));
				channel.write(channelBuffer);
			} catch (Exception e) {
				PrintUtil.err(e.getMessage());
			} finally {
				// lock.unlock();
			}
		}
		
	}

	public void close() {
		channel.close().awaitUninterruptibly();
		bootstrap.releaseExternalResources();
	}

	public boolean isConnected() {
		return channel != null && channel.isConnected() ? true : false;
	}

}
